﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Collections;
using System.Windows.Forms;

namespace TRAC_Demo
{
    // T.R.A.C.
    // Main Author(s): Morgan Davis
    // Additional Authors:
    // Date: 9/30/2013
    // Updated: 10/03/2013 to add dataGridReport print functionality

    public partial class FormGenerateReport : Form
    {
        #region [ Fields ]

        TRACobjectsDataContext tracObj = new TRACobjectsDataContext();

        // Printing variables
        ArrayList columnLefts = new ArrayList();
        ArrayList columnWidths = new ArrayList();
        StringFormat strFormat = new StringFormat();
        int cellHeight = 0;
        int totalWidth = 0;
        int row = 0;
        int headerHeight = 0;
        bool firstPage = true;
        bool newPage = true;

        #endregion

        #region [ Constructors ]

        public FormGenerateReport()
        {
            InitializeComponent();
            this.BackColor = CurrentUser.UserColor;
            dateStart.Format = DateTimePickerFormat.Custom;
            dateStart.CustomFormat = "MMMM dd, yyyy HHmm";
            dateEnd.Format = DateTimePickerFormat.Custom;
            dateEnd.CustomFormat = "MMMM dd, yyyy HHmm";
        }

        #endregion

        #region [ Events ]

        private void btnQuit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnExport_Click(object sender, EventArgs e)
        {
            ExportToExcel();
        }

        private void btnPrint_Click(object sender, EventArgs e) //begins the printing process
        {
            PrintDialog printReportDialog = new PrintDialog();
            printReportDialog.Document = printReport;
            printReportDialog.UseEXDialog = true;
            if (DialogResult.OK == printReportDialog.ShowDialog())
            {
                printReport.DocumentName = "TRAC Report";
                printReport.Print();
            }
        }

        // Applies a user selected filter
        private void btnApply_Click(object sender, EventArgs e)
        {
            if (chkResolved.Checked == true)
            {
                var mainQuery = from myData in tracObj.ResolvedTickets select myData;
                mainQuery = FilterQueryResolved(mainQuery);
                try
                {
                    dataGridReport.Columns.Clear();
                    DataGridViewButtonColumn col = new DataGridViewButtonColumn();
                    col.UseColumnTextForButtonValue = true;
                    col.Name = "View Ticket";
                    col.Text = "View Ticket";
                    dataGridReport.Columns.Add(col);
                    dataGridReport.DataSource = mainQuery;
                    
                    //because resolved tickets have an extra column containing the resolved date, therefore the datagrid control
                    //needs to be formated differently depending on whether or not the user is viewing active or resolved
                    //tickets
                    //the following block is for users viewing resolved tickets
                    if (chkResolved.Checked == true)
                    {
                        for (int i = 13; i > 10; i--)
                        {
                            dataGridReport.Columns.RemoveAt(i);
                        }
                        dataGridReport.Columns[10].Width = 500;
                        dataGridReport.Columns[8].Width = 70;
                        dataGridReport.Columns[7].Width = 70;
                        dataGridReport.Columns[6].Width = 80;
                        dataGridReport.Columns[5].Width = 78;
                        dataGridReport.Columns[4].Width = 130;
                        dataGridReport.Columns[3].Width = 130;
                        dataGridReport.Columns[2].Width = 70;
                        dataGridReport.Columns[1].Width = 80;
                        dataGridReport.Columns[0].Width = 78;
                        dataGridReport.Refresh();
                    }
                    else
                    {
                        for (int i = 12; i > 9; i--)
                        {
                            dataGridReport.Columns.RemoveAt(i);
                        }
                        dataGridReport.Columns[9].Width = 500;
                        dataGridReport.Refresh();
                    }
                }
                catch (FormatException)
                {

                    MessageBox.Show("Please only enter numerical data into the text boxes", "Stop that!");
                }
            }
                //the following block of code is the formatting for the datagrid object if the user is viewing
                //active tickets
            else 
            {
                var mainQuery = from myData in tracObj.Tickets select myData;
                mainQuery = FilterQuery(mainQuery);
                try
                {
                    dataGridReport.Columns.Clear();
                    DataGridViewButtonColumn col = new DataGridViewButtonColumn();
                    col.UseColumnTextForButtonValue = true;
                    col.Name = "View Ticket";
                    col.Text = "View Ticket";
                    dataGridReport.Columns.Add(col);
                    dataGridReport.DataSource = mainQuery;
                    for (int i = 12; i > 9; i--)
                    {
                        dataGridReport.Columns.RemoveAt(i);
                    }
                    dataGridReport.Columns[9].Width = 500;
                    dataGridReport.Refresh();
                }
                catch (FormatException)
                {

                    MessageBox.Show("Please only enter numerical data into the text boxes", "Stop that!");
                }

            }
        }
      
        private void dataGridReport_CellClick(object sender,
                    System.Windows.Forms.DataGridViewCellEventArgs e) //handles the click event of the dynamically generated
                                                                      //generated buttons in the datagrid control
        {        
            if (dataGridReport.Columns[e.ColumnIndex].Name == "View Ticket")
            {
                if (chkResolved.Checked == true) //handles viewing of tickets that are in the resolved ticket table
                {
                    int col = this.dataGridReport.CurrentCell.ColumnIndex;
                    int row = this.dataGridReport.CurrentCell.RowIndex;
                    int valueToPass = (int)(dataGridReport.Rows[row].Cells[1].Value);
                    if (valueToPass != 0) //make sure value isn't 0
                    {
                        Form FormResolvedTicketOverview = new FormResolvedTicketOverview(valueToPass);
                        FormResolvedTicketOverview.Show();
                    }
                    else
                        MessageBox.Show("Ticket Number Doesn't exist in the DataBase", "Ticket Doesn't Exist!");
                }
                else //handles viewing of tickets that are in the active ticket table
                {
                    int col = this.dataGridReport.CurrentCell.ColumnIndex;
                    int row = this.dataGridReport.CurrentCell.RowIndex;
                    int valueToPass = (int)(dataGridReport.Rows[row].Cells[1].Value);
                    if (valueToPass != 0) //make sure value isn't 0
                    {
                        Form FormTicketOverview = new FormTicketOverview(valueToPass);
                        FormTicketOverview.Show();
                    }
                    else
                        MessageBox.Show("Ticket Number Doesn't exist in the DataBase", "Ticket Doesn't Exist!");
                }
            }
        }

        //event handlers that call up dialog boxes so the user can view employee and agent data by either last name
        //or agent/employee id number
        #region [ ViewAgentEmployeeLists ]

        private void btnViewAgent_Click(object sender, EventArgs e)
        {
            Form agentList = new FormAgentList(true);
            agentList.ShowDialog();
        }

        private void btnViewEmp_Click(object sender, EventArgs e)
        {
            Form employeeList = new FormEmployeeList(true);
            employeeList.ShowDialog();
        }

        private void btnViewAgentName_Click(object sender, EventArgs e)
        {
            Form agentList = new FormAgentList();
            agentList.ShowDialog();
        }

        private void btnViewEmpName_Click(object sender, EventArgs e)
        {
            Form employeeList = new FormEmployeeList();
            employeeList.ShowDialog();
        }

        #endregion

        #endregion

        #region [ Methods ]

        //filters the query depending on which options the user has specified on the form
        private IQueryable<Ticket> FilterQuery(IQueryable<Ticket> mainQuery)
        {
            if (chkAgent.Checked == true)
            {
                if (txtAgent.Text != "")
                {
                    try
                    {
                        mainQuery = mainQuery.AsQueryable().Where(Ticket => Ticket.AssignedAgent == int.Parse(txtAgent.Text));
                    }
                    catch (FormatException)
                    {
                        MessageBox.Show("Please only enter numerical data into the text boxes", "Stop that!");
                    }
                }

            }

            if (chkEmployee.Checked == true)
            {
                if (txtEmployee.Text != "")
                {
                    try
                    {
                        mainQuery = mainQuery.AsQueryable().Where(Ticket => Ticket.EmployeeID == int.Parse(txtEmployee.Text));
                    }
                    catch (FormatException)
                    {
                        MessageBox.Show("Please only enter numerical data into the text boxes", "Stop that!");
                    }
                }
            }

            if (chkCreated.Checked == true)
            {
                if (txtCreated.Text != "")
                {
                    try
                    {
                        mainQuery = mainQuery.AsQueryable().Where(Ticket => Ticket.CreatingAgent == int.Parse(txtCreated.Text));
                    }
                    catch (FormatException)
                    {
                        MessageBox.Show("Please only enter numerical data into the text boxes", "Stop that!");
                    }
                }
            }

            if (chkStatus.Checked == true)
            {
                if (comboStatus.Text != "")
                {
                    try
                    {
                        mainQuery = mainQuery.AsQueryable().Where(Ticket => Ticket.StatusCode == comboStatus.Text);
                    }
                    catch (FormatException)
                    {
                        MessageBox.Show("Please select the status code from the drop down control.", "Stop that!");
                    }
                }
            }

            if (chkDate.Checked == true)
            {
                try
                {
                    mainQuery = mainQuery.AsQueryable().Where(Ticket => Ticket.DateCreated >= dateStart.Value);
                    mainQuery = mainQuery.AsQueryable().Where(Ticket => Ticket.DateCreated <= dateEnd.Value);
                }
                catch (FormatException)
                {
                    MessageBox.Show("Please only enter numerical data into the text boxes", "Stop that!");
                }
            }

            mainQuery = mainQuery.AsQueryable().OrderBy(Ticket => Ticket.TicketNumber);

            return mainQuery;
        }

        //filters the query based on user provided information on tickets contained in the resolved ticket table
        private IQueryable<ResolvedTicket> FilterQueryResolved(IQueryable<ResolvedTicket> mainQuery)
        {
            if (chkAgent.Checked == true)
            {
                if (txtAgent.Text != "")
                {
                    try
                    {
                        mainQuery = mainQuery.AsQueryable().Where(Ticket => Ticket.AssignedAgent == int.Parse(txtAgent.Text));
                    }
                    catch (FormatException)
                    {
                        MessageBox.Show("Please only enter numerical data into the text boxes", "Stop that!");
                    }
                }

            }

            if (chkEmployee.Checked == true)
            {
                if (txtEmployee.Text != "")
                {
                    try
                    {
                        mainQuery = mainQuery.AsQueryable().Where(Ticket => Ticket.EmployeeID == int.Parse(txtEmployee.Text));
                    }
                    catch (FormatException)
                    {
                        MessageBox.Show("Please only enter numerical data into the text boxes", "Stop that!");
                    }
                }
            }

            if (chkCreated.Checked == true)
            {
                if (txtCreated.Text != "")
                {
                    try
                    {
                        mainQuery = mainQuery.AsQueryable().Where(Ticket => Ticket.CreatingAgent == int.Parse(txtCreated.Text));
                    }
                    catch (FormatException)
                    {
                        MessageBox.Show("Please only enter numerical data into the text boxes", "Stop that!");
                    }
                }
            }

            if (chkStatus.Checked == true)
            {
                if (comboStatus.Text != "")
                {
                    try
                    {
                        mainQuery = mainQuery.AsQueryable().Where(Ticket => Ticket.StatusCode == comboStatus.Text);
                    }
                    catch (FormatException)
                    {
                        MessageBox.Show("Please select the status code from the drop down control.", "Stop that!");
                    }
                }
            }

            if (chkDate.Checked == true)
            {
                try
                {
                    mainQuery = mainQuery.AsQueryable().Where(Ticket => Ticket.DateCreated >= dateStart.Value);
                    mainQuery = mainQuery.AsQueryable().Where(Ticket => Ticket.DateCreated <= dateEnd.Value);
                }
                catch (FormatException)
                {
                    MessageBox.Show("Please only enter numerical data into the text boxes", "Stop that!");
                }
            }

            mainQuery = mainQuery.AsQueryable().OrderBy(Ticket => Ticket.TicketNumber);

            return mainQuery;
        }

        private void ExportToExcel()
        {
            int cols;
            //open file 
            StreamWriter wr = new StreamWriter("TRACreport.csv");

            //determine the number of columns and write columns to file 
            cols = dataGridReport.Columns.Count;
            for (int i = 0; i < cols - 1; i++)
            {
                wr.Write(dataGridReport.Columns[i].Name.ToString().ToUpper() + ",");
            }
            wr.WriteLine();

            //Write rows to CSV file
            for (int i = 0; i < (dataGridReport.Rows.Count - 1); i++)
            {
                for (int j = 0; j < cols; j++)
                {
                    if (dataGridReport.Rows[i].Cells[j].Value != null)
                    {
                        wr.Write(dataGridReport.Rows[i].Cells[j].Value + ",");
                    }
                    else
                    {
                        wr.Write(",");
                    }
                }

                wr.WriteLine();
            }

            //close file
            wr.Close();
        }

        #region [ Printing Methods ]

        private void printReport_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
        {
            strFormat.Alignment = StringAlignment.Near;
            strFormat.LineAlignment = StringAlignment.Center;
            strFormat.Trimming = StringTrimming.EllipsisCharacter;

            foreach (DataGridViewColumn dvgColumn in dataGridReport.Columns)
            {
                totalWidth += dvgColumn.Width;
            }

        }

        private void printReport_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            //variables that used to store the margin size
            int leftMargin = e.MarginBounds.Left;
            int topMargin = e.MarginBounds.Top;
            int tempWidth = 0;
            bool morePages = false;
            if (firstPage)
            {
                foreach (DataGridViewColumn gridCol in dataGridReport.Columns) //sets width and height margins
                {
                    tempWidth = (int)(Math.Floor(((double)gridCol.Width /
                        (double)totalWidth * (double)totalWidth * e.MarginBounds.Width /
                        (double)totalWidth)));
                    headerHeight = (int)(e.Graphics.MeasureString(gridCol.HeaderText,
                        gridCol.InheritedStyle.Font, tempWidth).Height) + 11;
                    columnLefts.Add(leftMargin);
                    columnWidths.Add(tempWidth);
                    leftMargin += tempWidth;
                }
                while (row <= dataGridReport.Rows.Count - 1) //checks to see if there are remaining rows that need to be accounted for
                {
                    DataGridViewRow gridRow = dataGridReport.Rows[row];
                    cellHeight = gridRow.Height + 5;
                    int counter = 0;
                    if (topMargin + cellHeight >= e.MarginBounds.Height + e.MarginBounds.Top) //determines if there are more pages to be printed
                    {
                        newPage = true;
                        firstPage = false;
                        morePages = true;
                        break;
                    }
                    else
                    {
                        if (newPage) //if there are more pages to print
                        {
                            e.Graphics.DrawString("TRAC Report",
                            new Font(dataGridReport.Font, FontStyle.Bold),
                            Brushes.Black, e.MarginBounds.Left,
                            e.MarginBounds.Top - e.Graphics.MeasureString("TRAC Report",
                            new Font(dataGridReport.Font, FontStyle.Bold),
                            e.MarginBounds.Width).Height - 13);

                            String strDate = DateTime.Now.ToLongDateString() + " " +
                            DateTime.Now.ToShortTimeString();

                            e.Graphics.DrawString(strDate,
                            new Font(dataGridReport.Font, FontStyle.Bold), Brushes.Black,
                            e.MarginBounds.Left +
                            (e.MarginBounds.Width - e.Graphics.MeasureString(strDate,
                            new Font(dataGridReport.Font, FontStyle.Bold),
                            e.MarginBounds.Width).Width),
                            e.MarginBounds.Top - e.Graphics.MeasureString("TRAC Report",
                            new Font(new Font(dataGridReport.Font, FontStyle.Bold),
                            FontStyle.Bold), e.MarginBounds.Width).Height - 13);

                            topMargin = e.MarginBounds.Top;
                            foreach (DataGridViewColumn GridCol in dataGridReport.Columns)
                            {
                                e.Graphics.FillRectangle(new SolidBrush(Color.LightGray),
                                new Rectangle((int)columnLefts[counter], topMargin,
                                (int)columnWidths[counter], headerHeight));
                                e.Graphics.DrawRectangle(Pens.Black,
                                new Rectangle((int)columnLefts[counter], topMargin,
                                (int)columnWidths[counter], headerHeight));
                                e.Graphics.DrawString(GridCol.HeaderText,
                                GridCol.InheritedStyle.Font,
                                new SolidBrush(GridCol.InheritedStyle.ForeColor),
                                new RectangleF((int)columnLefts[counter], topMargin,
                                (int)columnWidths[counter], headerHeight), strFormat);
                                counter++;
                            }
                            newPage = false;
                            topMargin += headerHeight;
                        }
                        counter = 0;
                        foreach (DataGridViewCell Cel in gridRow.Cells)
                        {
                            if (Cel.Value != null)
                            {
                                e.Graphics.DrawString(Cel.Value.ToString(),
                                Cel.InheritedStyle.Font,
                                new SolidBrush(Cel.InheritedStyle.ForeColor),
                                new RectangleF((int)columnLefts[counter],
                                (float)topMargin,
                                (int)columnWidths[counter], (float)cellHeight),
                                strFormat);
                            }
                            e.Graphics.DrawRectangle(Pens.Black,
                            new Rectangle((int)columnLefts[counter], topMargin,
                            (int)columnWidths[counter], cellHeight));
                            counter++;
                        }
                    }
                    row++;
                    topMargin += cellHeight;
                }
                if (morePages)
                    e.HasMorePages = true;
                else
                    e.HasMorePages = false;
            }
        }

        #endregion

        #endregion
    }
}
